#!/usr/bin/env node

// @ts-nocheck

process.on('unhandledRejection', (err) => {
  if (err.stderr) {
    return console.log(err.stderr);
  }
  throw err;
});

const execa = require('execa');
const chalk = require('chalk');
const path = require('path');
const fs = require('fs-extra');
const { workerRun } = require('./lib/workerRun');
const { _: args, ...cmdOpts } = require('minimist')(process.argv.slice(2));

const [origin, target] = args;

function showHelp() {
  console.log(`
  用法：

    cmove origin  target <option>
  
  选项:

    --rename   移动目录并重命名  例如： cmove src/foo src/bar --rename

  Example:
  
    cmove src/foo/bar.ts  src/bar.ts   # 移动文件           src/foo/bar.ts ==> src/bar.ts

    cmove src/foo/bar  src/            # 移动目录           src/foo/bar ==> src/bar
    
    cmove src/foo src/bar              # 移动目录           src/foo ==> src/bar/foo
    
    cmove src/foo src/bar --rename     # 移动目录并重命名   src/foo ==> src/bar
  `);
  process.exit(0);
}

function check() {
  if (args.length < 2) {
    showHelp();
  }

  const originState = fs.statSync(origin);

  if (path.extname(origin) && !path.extname(target)) {
    showHelp();
  }

  if (originState.isDirectory() && path.extname(target)) {
    showHelp();
  }
}

const shortPath = (fpath) => {
  return fpath.replace(/(\/index(\.tsx?)?|\.tsx?)$/m, '');
};

// 替换模块引用路径
(async () => {
  // 检测参数
  check();

  const originState = fs.statSync(origin);

  let from, to;

  // 移动文件
  if (originState.isFile()) {
    from = shortPath(origin);
    to = shortPath(target);
    // 目标目录已存在
    if (fs.pathExistsSync(to)) {
      throw new Error(chalk.red(to + ' 文件已经存'));
    }
    await execa('mkdir', ['-p', path.dirname(target)]);
  }

  // 移动目录
  // cmove src/foo src/bar --rename   移动目录并且重命名  src/foo ==> src/bar
  // cmove src/foo src/bar            移动目录  src/foo ==> src/bar/foo
  if (originState.isDirectory()) {
    from = origin;
    to = cmdOpts.rename ? target : path.join(target, path.basename(origin));

    // 目标目录已存在
    if (!cmdOpts.rename && fs.pathExistsSync(to)) {
      throw new Error(chalk.red(to + ' 已经存，请先清理目录'));
    }

    if (!cmdOpts.rename) {
      await execa('mkdir', ['-p', target]);
    }
  }

  // 引用路径替换 from , to 透传给 tosrc.js
  await workerRun(require.resolve('./mod/tosrc.js'), { globPattern: 'src/**/*.{ts,tsx,js,scss}', from, to });

  const appendStash = (str) => (str.slice(-1) === '/' ? str : str + '/');

  if (originState.isDirectory() && cmdOpts.rename) {
    // 移动目录并重命名
    await execa('cp', ['-R', appendStash(args[0]), args[1]]);
    await execa('rm', ['-rf', args[0]]);
  } else {
    // 移动目录
    await execa('mv', args);
  }
})();
